/* Copyright (C) 2007-2008  klevgert  http://code.google.com/p/db4o-netbeans/

This file is part of the db4o-netbeans module suite.

db4o-netbeans is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation and as clarified by db4objects' GPL 
interpretation policy, available at
http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
Suite 350, San Mateo, CA 94403, USA.

db4o-netbeans is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */

package com.db4o.nb.editor;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.nb.api.Db4oProvider;
import com.db4o.nb.api.impl.Db4oDatabaseImpl;
import com.db4o.nb.editor.nodes.DatabaseNode;
import com.db4o.nb.editor.nodes.Db4oDataNode;
import com.db4o.nb.editor.nodes.ObjectSetNode;
import com.db4o.nb.editor.tableview.Db4oEditorTableViewTopComponent;
import com.db4o.nb.util.PreferencesUtil;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.Action;

import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.text.DefaultEditorKit;
import org.openide.actions.PropertiesAction;

import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.BeanTreeView;
import org.openide.explorer.view.TreeTableView;
import org.openide.loaders.DataObject;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.util.actions.SystemAction;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
import org.openide.windows.TopComponent;

/**
 * Db4o Database Editor.
 *
 * @author  klevgert
 */
public class Db4oDataEditor 
    extends TopComponent 
    implements ExplorerManager.Provider, Lookup.Provider {

  /** path to the icon used by the component and its open action */
  static final String EDITOR_ICON_PATH = "com/db4o/nb/editor/resources/beantree.gif";

  private final ExplorerManager mgr = new ExplorerManager();
  private final InstanceContent content = new InstanceContent();
  
  /**
   * Map used to group editor instances belonging to one provider
   * together. This is used to know when a db4o database has to be closed. 
   */
  static Map lockMap = new HashMap();
      
  /** Creates new form Db4oDataEditor */
  public Db4oDataEditor() {
    initComponents();
    
    jPanel1.remove(jScrollPane1);
    jScrollPane1 = new TreeTableView();
    jPanel1.add(jScrollPane1, BorderLayout.CENTER);
    
    this.setDisplayName(NbBundle.getMessage(Db4oOpenDataEditor.class, "CTL_Db4oOpenDataEditor"));
    this.setIcon(Utilities.loadImage(EDITOR_ICON_PATH, true));
    
    ActionMap map = getActionMap();
    map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(mgr));
    map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(mgr));
    map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(mgr));
    map.put("delete", ExplorerUtils.actionDelete(mgr, true));

    associateLookup (ExplorerUtils.createLookup(mgr, map));
//    associateLookup (new AbstractLookup (content)); 
    content.set(Collections.singleton(mgr),null);

  }
  
  public int getPersistenceType() {
    return PERSISTENCE_NEVER;
  }
  
  public ExplorerManager getExplorerManager() {
    return mgr;
  }

  /**
   * Callback if a db4o database editor is opened.
   * This instance is added to static member list to track
   * that db4o database is closed when the last editor is closed.
   */
  protected void componentOpened() {
    Node node = mgr.getExploredContext();
    DataObject dataObj = (DataObject)node.getLookup().lookup(DataObject.class);
    
    if( !lockMap.containsKey(dataObj) ) {
      lockMap.put(dataObj, new ArrayList());
    }
    List l = (List) lockMap.get(dataObj);
    l.add(this);
  }

  /**
   * Callback if a db4o database editor is closed.
   * This instance is searched in the static member list to track
   * that db4o database is closed when the last editor is closed.
   */
  protected void componentClosed() {
    Node node = mgr.getExploredContext();
    DataObject dataObj = (DataObject)node.getLookup().lookup(DataObject.class);
    
    List l = (List) lockMap.get(dataObj);
    l.remove(this);
    if( l.isEmpty() ) {
      lockMap.remove(dataObj);
      
      Db4oProvider provider = (Db4oProvider) dataObj.getNodeDelegate().getLookup().lookup(Db4oProvider.class);
      if( provider != null ) {
        provider.getDatabase().disconnect();
      }
    }
  }

  protected void componentActivated() {
      ExplorerUtils.activateActions(mgr, true);
  }
  protected void componentDeactivated() {
      ExplorerUtils.activateActions(mgr, false);
  }

  
  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  // <editor-fold defaultstate="collapsed" desc=" Erzeugter Quelltext ">//GEN-BEGIN:initComponents
  private void initComponents() {
    jPanel1 = new javax.swing.JPanel();
    jScrollPane1 = new javax.swing.JScrollPane();
    jToolBar1 = new javax.swing.JToolBar();
    btnProperties = new javax.swing.JButton();
    btnListView = new javax.swing.JButton();

    setLayout(new java.awt.BorderLayout());

    setPreferredSize(new java.awt.Dimension(250, 100));
    jPanel1.setLayout(new java.awt.BorderLayout());

    jScrollPane1.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyPressed(java.awt.event.KeyEvent evt) {
        jScrollPane1KeyPressed(evt);
      }
    });

    jPanel1.add(jScrollPane1, java.awt.BorderLayout.CENTER);

    add(jPanel1, java.awt.BorderLayout.CENTER);

    jToolBar1.setFloatable(false);
    btnProperties.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/db4o/nb/editor/resources/properties.gif")));
    btnProperties.setToolTipText("Show Properties");
    btnProperties.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        btnPropertiesActionPerformed(evt);
      }
    });

    jToolBar1.add(btnProperties);

    btnListView.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/db4o/nb/editor/resources/table.gif")));
    btnListView.setToolTipText("Show Table");
    btnListView.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        btnListViewActionPerformed(evt);
      }
    });

    jToolBar1.add(btnListView);

    add(jToolBar1, java.awt.BorderLayout.NORTH);

  }// </editor-fold>//GEN-END:initComponents

  private void btnListViewActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btnListViewActionPerformed

    TopComponent win = Db4oEditorTableViewTopComponent.findInstance();
    win.open();
    win.requestActive();
    
  }//GEN-LAST:event_btnListViewActionPerformed

  private void btnPropertiesActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btnPropertiesActionPerformed

   Action propertiesAction = SystemAction.get(PropertiesAction.class);
   propertiesAction.actionPerformed(null);
    
  }//GEN-LAST:event_btnPropertiesActionPerformed

  private void jScrollPane1KeyPressed(KeyEvent evt) {//GEN-FIRST:event_jScrollPane1KeyPressed


  }//GEN-LAST:event_jScrollPane1KeyPressed
  
  
  // Variablendeklaration - nicht modifizieren//GEN-BEGIN:variables
  private javax.swing.JButton btnListView;
  private javax.swing.JButton btnProperties;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JToolBar jToolBar1;
  // Ende der Variablendeklaration//GEN-END:variables
  
}
